package com.cinyi.cyds.base.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.cinyi.cyds.base.bean.DataGrid;
import com.cinyi.cyds.base.bean.PageHelper;
import com.cinyi.cyds.base.bean.SessionInfo;
import com.cinyi.cyds.base.bean.User;
import com.cinyi.cyds.base.model.Tresource;
import com.cinyi.cyds.base.model.Trole;
import com.cinyi.cyds.base.model.Tuser;
import com.cinyi.cyds.base.service.UserServiceI;
import com.cinyi.cyds.util.MD5Util;
import com.cinyi.ormlite.web.dao.DefaultJdbcDaoImpl;

@Service
public class UserServiceImpl implements UserServiceI {
    protected Log logger = LogFactory.getLog(UserServiceImpl.class);
    
	private DefaultJdbcDaoImpl<Trole> roleDao ;
	private DefaultJdbcDaoImpl<Tuser> userDao;
	private DefaultJdbcDaoImpl<Tresource> resourceDao;
	
	public UserServiceImpl(){
		roleDao = new DefaultJdbcDaoImpl<Trole>();
		userDao = new DefaultJdbcDaoImpl<Tuser>();
		resourceDao = new DefaultJdbcDaoImpl<Tresource>();
	}

	@Override
	public User login(User user) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("name", user.getName());
		params.put("pwd", MD5Util.md5(user.getPwd()));
		List<Tuser> tusers = userDao.find(Tuser.class, params,null);
		if (tusers != null && tusers.size() > 0) {
			Tuser t = tusers.get(0);
			BeanUtils.copyProperties(t, user);
			return user;
		}
		return null;
	}

	@Override
	synchronized public void reg(User user) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("name", user.getName());
		if (userDao.count(params, Tuser.class) > 0) {
			throw new Exception("登录名已存在！");
		} else {
			Tuser u = new Tuser();
			u.setId(UUID.randomUUID().toString());
			u.setName(user.getName());
			u.setPwd(MD5Util.md5(user.getPwd()));
			u.setCreatedatetime(new Date());
			userDao.save(u);
		}
	}

	@Override
	public DataGrid dataGrid(User user, PageHelper ph) throws Exception {
		DataGrid dg = new DataGrid();
		List<User> ul = new ArrayList<User>();
		List<Object> findParam = new ArrayList<Object>();
		List<Object> countParam = new ArrayList<Object>();
		String hql = " select t.ID as id,t.CREATEDATETIME as createdatetime,t.MODIFYDATETIME as modifydatetime,t.name as name,t.pwd as pwd from tuser t ";
		List<Tuser> l = new ArrayList<Tuser>();
		try {
			l = userDao.findBySQL(Tuser.class, hql + whereHql(user, findParam)
					+ orderHql(ph), findParam, ph.getPage(), ph.getRows());
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		if (l != null && l.size() > 0) {
			for (Tuser t : l) {
				User u = new User();
				BeanUtils.copyProperties(t, u);
				List<Trole> roles = getRolesByUser(t.getId());
				if (roles != null && !roles.isEmpty()) {
					String roleIds = "";
					String roleNames = "";
					boolean b = false;
					for (Trole tr : roles) {
						if (b) {
							roleIds += ",";
							roleNames += ",";
						} else {
							b = true;
						}
						roleIds += tr.getId();
						roleNames += tr.getName();
					}
					u.setRoleIds(roleIds);
					u.setRoleNames(roleNames);
				}
				ul.add(u);
			}
		}
		dg.setRows(ul);
		dg.setTotal(userDao.count(
				"select count(*) from tuser t " + whereHql(user, countParam),
				countParam));
		return dg;
	}

	private String whereHql(User user, List<Object> params) {
		String hql = "";
		if (user != null) {
			hql += " where 1=1 ";
			if (StringUtils.isNotBlank(user.getName())) {
				hql += " and t.name like ?";
				params.add("%" + user.getName() + "%");
			}
			if (user.getCreatedatetimeStart() != null) {
				hql += " and t.createdatetime >= ?";
				params.add(user.getCreatedatetimeStart());
			}
			if (user.getCreatedatetimeEnd() != null) {
				hql += " and t.createdatetime <= ?";
				params.add(user.getCreatedatetimeEnd());
			}
			if (user.getModifydatetimeStart() != null) {
				hql += " and t.modifydatetime >= ?";
				params.add(user.getModifydatetimeStart());
			}
			if (user.getModifydatetimeEnd() != null) {
				hql += " and t.modifydatetime <= ?";
				params.add(user.getModifydatetimeEnd());
			}
		}
		return hql;
	}

	private String orderHql(PageHelper ph) {
		String orderString = "";
		if (ph.getSort() != null && ph.getOrder() != null) {
			orderString = " order by t." + ph.getSort() + " " + ph.getOrder();
		}
		return orderString;
	}

	@Override
	synchronized public void add(User user) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("name", user.getName());
		if (userDao.count(params, Tuser.class) > 0) {
			throw new Exception("登录名已存在！");
		} else {
			Tuser u = new Tuser();
			BeanUtils.copyProperties(user, u);
			u.setCreatedatetime(new Date());
			u.setPwd(MD5Util.md5(user.getPwd()));
			userDao.save(u);
		}
	}

	@Cacheable(value="userCache", key="'get'+#id")  
	@Override
	public User get(String id) throws Exception {
	    logger.error("# get user:"+id);
		Tuser t = userDao.get(id, Tuser.class);
		List<Trole> roles = getRolesByUser(id);
		User u = new User();
		BeanUtils.copyProperties(t, u);
		if (roles != null && !roles.isEmpty()) {
			String roleIds = "";
			String roleNames = "";
			boolean b = false;
			for (Trole role : roles) {
				if (b) {
					roleIds += ",";
					roleNames += ",";
				} else {
					b = true;
				}
				roleIds += role.getId();
				roleNames += role.getName();
			}
			u.setRoleIds(roleIds);
			u.setRoleNames(roleNames);
		}
		return u;
	}

	@CacheEvict(value="userCache", key="'get'+#id")  
	@Override
	synchronized public void edit(User user) throws Exception {
	    logger.error("# edit user:"+ user.getId());
		List<Object> params = new ArrayList<Object>();
		params.add(user.getName());
		params.add(user.getId());
		if (userDao.count(
				"select count(*) from tuser t where t.name =? and t.id != ? ",
				params) > 0) {
			throw new Exception("登录名已存在！");
		} else {
			Tuser u = userDao.get(user.getId(), Tuser.class);
			BeanUtils.copyProperties(user, u, new String[] { "pwd",
					"createdatetime" });
			u.setModifydatetime(new Date());
			userDao.saveOrUpdate(u);
		}
	}

	@CacheEvict(value="userCache", allEntries=true)  
	@Override
	public void delete(String id) {
	    logger.error("# delete user:"+ id);
		try {
			userDao.delete(id, Tuser.class);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public void grant(String ids, User user) throws Exception {
		if (ids != null && ids.length() > 0) {
			List<Trole> roles = new ArrayList<Trole>();
			if (user.getRoleIds() != null) {
				for (String roleId : user.getRoleIds().split(",")) {
					roles.add(roleDao.get(roleId, Trole.class));
				}
			}
			for (String id : ids.split(",")) {
				if (id != null && !id.equalsIgnoreCase("")) {
					Tuser t = userDao.get(id, Tuser.class);
					t.setTroles(new HashSet<Trole>(roles));
					for (Trole role : roles) {
						String delete_sql = "delete from tuser_trole where tuser_id = '"
								+ id + "'";
						userDao.executeSQL(delete_sql, null);
						List<Object> params = new ArrayList<Object>();
						params.add(id);
						params.add(role.getId());
						String insert_sql = "insert into tuser_trole(tuser_id,trole_id) values(?,?)";
						userDao.executeSQL(insert_sql, params);
					}
				}
			}
		}
	}

	@Override
	public List<String> resourceList(String id) {
		List<String> resourceList = new ArrayList<String>();
		try {
			Tuser t = userDao.get(id, Tuser.class);
			if (t != null) {
				List<Trole> roles = getRolesByUser(id);
				if (roles != null && !roles.isEmpty()) {
					for (Trole role : roles) {
						String tresource_sql = "select distinct t.ID as id,t.ICON as icon,t.NAME as name,t.REMARK as remark,t.SEQ as seq,t.URL as url,t.PID as pid,t.tresourcetypeId as tresourcetypeId from tresource t where id in(select tresource_id from trole_tresource where trole_id = '"
								+ role.getId() + "')";
						List<Tresource> resources = resourceDao.findBySQL(
								Tresource.class, tresource_sql);
						if (resources != null && !resources.isEmpty()) {
							for (Tresource resource : resources) {
								if (resource != null
										&& resource.getUrl() != null) {
									resourceList.add(resource.getUrl());
								}
							}
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return resourceList;
	}

	@Override
	public List<Trole> getRolesByUser(String id) throws Exception {
		String role_sql = "select distinct t.ID as id,t.NAME as name,t.REMARK as remark,t.SEQ as seq,t.PID as pid from trole t where id in(select trole_id from tuser_trole where tuser_id = '"
				+ id + "')";
		List<Trole> roles = roleDao.findBySQL(Trole.class, role_sql);
		return roles;
	}

	@Override
	public void editPwd(User user) {
		if (user != null && user.getPwd() != null
				&& !user.getPwd().trim().equalsIgnoreCase("")) {
			try {
				Tuser u = userDao.get(user.getId(), Tuser.class);
				u.setPwd(MD5Util.md5(user.getPwd()));
				u.setModifydatetime(new Date());
				userDao.saveOrUpdate(u);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	@Override
	public boolean editCurrentUserPwd(SessionInfo sessionInfo, String oldPwd,
			String pwd) {
		try {
			Tuser u = userDao.get(sessionInfo.getId(), Tuser.class);
			if (u.getPwd().equalsIgnoreCase(MD5Util.md5(oldPwd))) {// 说明原密码输入正确
				u.setPwd(MD5Util.md5(pwd));
				u.setModifydatetime(new Date());
				userDao.saveOrUpdate(u);
				return true;
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	@Override
	public List<User> loginCombobox(String q) {
		if (q == null) {
			q = "";
		}
		List<Tuser> tl = new ArrayList<Tuser>();
		try {
			tl = userDao
					.findBySQL(
							Tuser.class,
							"select t.ID as id,t.CREATEDATETIME as createdatetime,t.MODIFYDATETIME as modifydatetime,t.name as name,t.pwd as pwd  from tuser t where t.name like '%"
									+ q.trim() + "%' order by name", null, 1,
							10);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		List<User> ul = new ArrayList<User>();
		if (tl != null && tl.size() > 0) {
			for (Tuser t : tl) {
				User u = new User();
				u.setName(t.getName());
				ul.add(u);
			}
		}
		return ul;
	}

	@Override
	public DataGrid loginCombogrid(String q, PageHelper ph) {
		if (q == null) {
			q = "";
		}
		DataGrid dg = new DataGrid();
		List<User> ul = new ArrayList<User>();
		List<Tuser> tl = new ArrayList<Tuser>();
		try {
			tl = userDao
					.findBySQL(
							Tuser.class,
							"select t.ID as id,t.CREATEDATETIME as createdatetime,t.MODIFYDATETIME as modifydatetime,t.name as name,t.pwd as pwd  from tuser t where t.name like %"
									+ q.trim()
									+ "% order by "
									+ ph.getSort()
									+ " " + ph.getOrder(), null, ph.getPage(),
							ph.getRows());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (tl != null && tl.size() > 0) {
			for (Tuser t : tl) {
				User u = new User();
				u.setName(t.getName());
				u.setCreatedatetime(t.getCreatedatetime());
				u.setModifydatetime(t.getModifydatetime());
				ul.add(u);
			}
		}
		dg.setRows(ul);

		Long total = 0l;
		try {
			total = userDao
					.count("select count(*) from tuser t where t.name like '%"
							+ q.trim() + "%'");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		dg.setTotal(total);
		return dg;
	}

	@Override
	public List<Long> userCreateDatetimeChart() {
		List<Long> l = new ArrayList<Long>();
		int k = 0;
		for (int i = 0; i < 12; i++) {
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("s", k);
			params.put("e", k + 2);
			k = k + 2;
			try {
				l.add(userDao
						.count("select count(*) from tuser t where HOUR(t.createdatetime)>=:s and HOUR(t.createdatetime)<:e"));
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return l;
	}

}
